#include "ObserverEventInterface.hpp"

#include "observer/WsfPlatformObserver.hpp"
#include "observer/WsfTrackObserver.hpp"
#include "observer/WsfSimulationObserver.hpp"
#include "observer/WsfAdvancedBehaviorObserver.hpp"
#include "observer/WsfBehaviorObserver.hpp"
#include "observer/WsfCommObserver.hpp"
#include "observer/WsfDisObserver.hpp"
#include "observer/WsfExchangeObserver.hpp"
#include "observer/WsfFuelObserver.hpp"
#include "observer/WsfMoverObserver.hpp"
#include "observer/WsfPlatformPartObserver.hpp"
#include "observer/WsfProcessorObserver.hpp"
#include "observer/WsfQuantumTaskerObserver.hpp"
#include "observer/WsfScriptStateMachineObserver.hpp"
#include "observer/WsfSensorObserver.hpp"
#include "observer/WsfTaskObserver.hpp"
#include "observer/WsfWeaponObserver.hpp"
#include "observer/WsfWeaponTaskObserver.hpp"
#include "observer/WsfZoneObserver.hpp"
#include "GenUDP_Connection.hpp"

ObserverEventInterface::ObserverEventInterface(UtCallbackHolder &callBackes, GenUDP_Connection *conn)
{
    initCallBack(callBackes);
    mConnectionPtr = conn;
}

void ObserverEventInterface::initCallBack(UtCallbackHolder &callbacks)
{
    // WsfPlatformObserver 所有事件
    callbacks.Add(WsfObserver::PlatformAdded(&GetSimulation()).Connect(&ObserverEventInterface::PlatformAdded, this));           // 平台添加
    callbacks.Add(WsfObserver::PlatformDeleted(&GetSimulation()).Connect(&ObserverEventInterface::PlatformDeleted, this));       // 平台删除
    callbacks.Add(WsfObserver::MoverUpdated(&GetSimulation()).Connect(&ObserverEventInterface::MoverUpdated, this));                       // 移动更新
    callbacks.Add(WsfObserver::SensorTrackUpdated(&GetSimulation()).Connect(&ObserverEventInterface::SensorTrackUpdated, this)); // 传感器航迹更新

    // WsfSensorObserver 所有事件
    callbacks.Add(WsfObserver::SensorScanUpdated(&GetSimulation()).Connect(&ObserverEventInterface::SensorScanUpdated, this)); // 传感器扫描更新

    // WsfSimulationObserver 所有事件
    callbacks.Add(WsfObserver::RequestTimeAdvance(&GetSimulation()).Connect(&ObserverEventInterface::RequestTimeAdvance, this));               // 请求时间推进
    callbacks.Add(WsfObserver::SimulationClockRateChange(&GetSimulation()).Connect(&ObserverEventInterface::SimulationClockRateChange, this)); // 仿真时钟速率变化
    callbacks.Add(WsfObserver::SimulationInitializing(&GetSimulation()).Connect(&ObserverEventInterface::SimulationInitializing, this));       // 仿真初始化
    callbacks.Add(WsfObserver::SimulationStarting(&GetSimulation()).Connect(&ObserverEventInterface::SimulationStarting, this));               // 仿真启动
    callbacks.Add(WsfObserver::SimulationPausing(&GetSimulation()).Connect(&ObserverEventInterface::SimulationPausing, this));                 // 仿真暂停
    callbacks.Add(WsfObserver::SimulationResuming(&GetSimulation()).Connect(&ObserverEventInterface::SimulationResuming, this));               // 仿真恢复
    callbacks.Add(WsfObserver::SimulationComplete(&GetSimulation()).Connect(&ObserverEventInterface::SimulationComplete, this));               // 仿真完成

    // WsfTrackObserver 所有事件
    callbacks.Add(WsfObserver::LocalTrackDropped(&GetSimulation()).Connect(&ObserverEventInterface::LocalTrackDropped, this));       // 本地航迹丢弃
    callbacks.Add(WsfObserver::LocalTrackInitiated(&GetSimulation()).Connect(&ObserverEventInterface::LocalTrackInitiated, this));   // 本地航迹创建
    callbacks.Add(WsfObserver::LocalTrackUpdated(&GetSimulation()).Connect(&ObserverEventInterface::LocalTrackUpdated, this));       // 本地航迹更新
    callbacks.Add(WsfObserver::SensorTrackCoasted(&GetSimulation()).Connect(&ObserverEventInterface::SensorTrackCoasted, this));     // 传感器航迹惯性推算
    callbacks.Add(WsfObserver::SensorTrackDropped(&GetSimulation()).Connect(&ObserverEventInterface::SensorTrackDropped, this));     // 传感器航迹丢弃
    callbacks.Add(WsfObserver::SensorTrackInitiated(&GetSimulation()).Connect(&ObserverEventInterface::SensorTrackInitiated, this)); // 传感器航迹创建

    // WsfWeaponObserver
    callbacks.Add(WsfObserver::WeaponFireAborted(&GetSimulation()).Connect(&ObserverEventInterface::WeaponFireAborted, this));               // 武器开火中止
    callbacks.Add(WsfObserver::WeaponFired(&GetSimulation()).Connect(&ObserverEventInterface::WeaponFired, this));                           // 武器开火
    callbacks.Add(WsfObserver::WeaponFireRequested(&GetSimulation()).Connect(&ObserverEventInterface::WeaponFireRequested, this));           // 武器开火请求
    callbacks.Add(WsfObserver::WeaponPlatformPendingAdd(&GetSimulation()).Connect(&ObserverEventInterface::WeaponPlatformPendingAdd, this)); // 武器平台待添加
    callbacks.Add(WsfObserver::WeaponHit(&GetSimulation()).Connect(&ObserverEventInterface::WeaponHit, this));                               // 武器命中
    callbacks.Add(WsfObserver::WeaponKilled(&GetSimulation()).Connect(&ObserverEventInterface::WeaponKilled, this));                         // 武器摧毁
    callbacks.Add(WsfObserver::WeaponMissed(&GetSimulation()).Connect(&ObserverEventInterface::WeaponMissed, this));                         // 武器未命中
}

void ObserverEventInterface::PlatformAdded(double aSimTime, WsfPlatform *aPlatformPtr)
{
    // 获取经纬度信息
    double lat, lon, alt;
    aPlatformPtr->GetLocationLLA(lat, lon, alt);

    // 获取姿态信息
    double heading, pitch, roll;
    aPlatformPtr->GetOrientationNED(heading, pitch, roll);

    // 拼接json串
    Json::Value root;

    root["MsgType"] = Json::Value("PlatformAdded");
    root["WallTime"] = Json::Value(aSimTime);

    root["PlatformID"] = Json::Value((int)aPlatformPtr->GetIndex());
    root["PlatformName"] = Json::Value(aPlatformPtr->GetName());
    root["PlatformType"] = Json::Value(aPlatformPtr->GetType());
    root["PlatformSide"] = Json::Value(aPlatformPtr->GetSide());

    // 分组
    std::string groupsInfo;
    for (auto str : aPlatformPtr->GetGroups().GetGroupList())
    {
        groupsInfo.append(str.GetString());
    }
    if (aPlatformPtr->GetGroups().GetGroupList().size() > 0)
        root["PlatformGroup"] = Json::Value(aPlatformPtr->GetGroups().GetGroupList()[0].GetString());

    // 传感器
    root["Location"].append(lat);
    root["Location"].append(lon);
    root["Location"].append(alt);

    root["Orientation"].append(heading);
    root["Orientation"].append(pitch);
    root["Orientation"].append(roll);

    Json::FastWriter fw;
    std::string msg = fw.write(root);

    SendPacket(msg);
}

void ObserverEventInterface::PlatformDeleted(double aSimTime, WsfPlatform *aPlatformPtr)
{
    // 拼接json串
    Json::Value root;

    root["MsgType"] = Json::Value("PlatformDelete");
    root["WallTime"] = Json::Value(aSimTime);

    root["PlatformID"] = Json::Value((int)aPlatformPtr->GetIndex());
    root["PlatformName"] = Json::Value(aPlatformPtr->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);

    SendPacket(msg);
}

void ObserverEventInterface::MoverUpdated(double aSimTime, WsfMover *mvr)
{
    WsfPlatform *aPlatformPtr = mvr->GetPlatform();

    if (!aPlatformPtr)
        return;

    double lat, lon, alt;
    aPlatformPtr->GetLocationLLA(lat, lon, alt);

    double heading, pitch, roll;
    aPlatformPtr->GetOrientationNED(heading, pitch, roll);

    // 拼接json串
    Json::Value root;

    root["MsgType"] = Json::Value("MoverUpdated");
    root["WallTime"] = Json::Value(aSimTime);

    root["PlatformID"] = Json::Value((int)aPlatformPtr->GetIndex());
    root["PlatformName"] = Json::Value(aPlatformPtr->GetName());
    root["PlatformType"] = Json::Value(aPlatformPtr->GetType());
    root["PlatformSide"] = Json::Value(aPlatformPtr->GetSide());

    root["Location"].append(lat);
    root["Location"].append(lon);
    root["Location"].append(alt);

    root["Orientation"].append(heading);
    root["Orientation"].append(pitch);
    root["Orientation"].append(roll);

    Json::FastWriter fw;
    std::string msg = fw.write(root);

    SendPacket(msg);
}

void ObserverEventInterface::SensorTrackUpdated(double aSimTime, WsfSensor *aSensorPtr, const WsfTrack *aTrackPtr)
{
    double lat, lon, alt;
    aTrackPtr->GetLocationLLA(lat, lon, alt);

    // 拼接json串
    Json::Value root;

    root["MsgType"] = Json::Value("SensorTrackUpdate");
    root["WallTime"] = Json::Value(aSimTime);

    root["SensorID"] = Json::Value((int)aSensorPtr->GetPlatform()->GetIndex());
    root["SensorName"] = Json::Value(aSensorPtr->GetName());
    root["TargetIndex"] = Json::Value(aTrackPtr->GetTargetIndex());

    root["Location"].append(lat);
    root["Location"].append(lon);
    root["Location"].append(alt);

    Json::FastWriter fw;
    std::string msg = fw.write(root);

    SendPacket(msg);
}

void ObserverEventInterface::SendPacket(const std::string &aMessage)
{
    int bytesWritten = mConnectionPtr->SendBuffer(aMessage.c_str(), ut::cast_to_int(aMessage.length() + 1));
    if (bytesWritten < 0)
    {
        ut::log::error() << "Socket error: " << GenSockets::GenSocketManager::GetLastError();
    }
}

void ObserverEventInterface::SensorScanUpdated(double aSimTime, WsfSensor *aSensor)
{
    Json::Value root;
    root["MsgType"] = Json::Value("SensorScanUpdated");
    root["WallTime"] = Json::Value(aSimTime);
    root["SensorID"] = Json::Value((int)aSensor->GetPlatform()->GetIndex());
    root["SensorName"] = Json::Value(aSensor->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}

// WsfSimulationObserver
void ObserverEventInterface::RequestTimeAdvance(double aSimTime, double aRequestedTime, double aGrantedTime)
{
    Json::Value root;
    root["MsgType"] = Json::Value("RequestTimeAdvance");
    root["WallTime"] = Json::Value(aSimTime);
    root["RequestedTime"] = Json::Value(aRequestedTime);
    root["GrantedTime"] = Json::Value(aGrantedTime);

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SimulationClockRateChange(double aSimTime)
{
    Json::Value root;
    root["MsgType"] = Json::Value("SimulationClockRateChange");
    root["WallTime"] = Json::Value(aSimTime);
    root["ClockRate"] = Json::Value(GetSimulation().GetClockRate());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SimulationInitializing()
{
    Json::Value root;
    root["MsgType"] = Json::Value("SimulationInitializing");
    root["WallTime"] = Json::Value(GetSimulation().GetSimTime());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SimulationStarting()
{
    Json::Value root;
    root["MsgType"] = Json::Value("SimulationStarting");
    root["WallTime"] = Json::Value(GetSimulation().GetSimTime());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SimulationPausing()
{
    Json::Value root;
    root["MsgType"] = Json::Value("SimulationPausing");
    root["WallTime"] = Json::Value(GetSimulation().GetSimTime());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SimulationResuming()
{
    Json::Value root;
    root["MsgType"] = Json::Value("SimulationResuming");
    root["WallTime"] = Json::Value(GetSimulation().GetSimTime());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SimulationComplete(double aSimTime)
{
    Json::Value root;
    root["MsgType"] = Json::Value("SimulationComplete");
    root["WallTime"] = Json::Value(aSimTime);

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}

// WsfTrackObserver
void ObserverEventInterface::LocalTrackDropped(double aSimTime, WsfPlatform *aPlatform, const WsfLocalTrack *aTrack)
{
    Json::Value root;
    root["MsgType"] = Json::Value("LocalTrackDropped");
    root["WallTime"] = Json::Value(aSimTime);
    root["PlatformID"] = Json::Value((int)aPlatform->GetIndex());
    root["PlatformName"] = Json::Value(aPlatform->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::LocalTrackInitiated(double aSimTime, WsfPlatform *aPlatform, const WsfLocalTrack *aLocalTrack, const WsfTrack *aSensorTrack)
{
    Json::Value root;
    root["MsgType"] = Json::Value("LocalTrackInitiated");
    root["WallTime"] = Json::Value(aSimTime);
    root["PlatformID"] = Json::Value((int)aPlatform->GetIndex());
    root["PlatformName"] = Json::Value(aPlatform->GetName());
    // root["trackName"] = Json::Value(1);

    //////获取轨迹
    // unsigned int trackId1 = aPlatform->GetTrackManager().GetRawTrackCount();
    // unsigned int trackId2 = aPlatform->GetTrackManager().GetTrackCount();
    // root["trackName1"] = Json::Value(trackId1);
    // root["trackName2"] = Json::Value(trackId2);
    // WsfTrack* track = aPlatform->GetTrackManager().GetTrackEntry(trackId2 - 1);
    // if (!track)
    //	ut::log::info() << "err no track";
    // else
    //	root["trackName"] = Json::Value(track->GetTargetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::LocalTrackUpdated(double aSimTime, WsfPlatform *aPlatform, const WsfLocalTrack *aLocalTrack, const WsfTrack *aSensorTrack)
{
    Json::Value root;
    root["MsgType"] = Json::Value("LocalTrackUpdated");
    root["WallTime"] = Json::Value(aSimTime);
    root["PlatformID"] = Json::Value((int)aPlatform->GetIndex());
    root["PlatformName"] = Json::Value(aPlatform->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SensorTrackCoasted(double aSimTime, WsfSensor *aSensor, const WsfTrack *aTrack)
{
    Json::Value root;
    root["MsgType"] = Json::Value("SensorTrackCoasted");
    root["WallTime"] = Json::Value(aSimTime);
    root["SensorID"] = Json::Value((int)aSensor->GetPlatform()->GetIndex());
    root["SensorName"] = Json::Value(aSensor->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SensorTrackDropped(double aSimTime, WsfSensor *aSensor, const WsfTrack *aTrack)
{
    Json::Value root;
    root["MsgType"] = Json::Value("SensorTrackDropped");
    root["WallTime"] = Json::Value(aSimTime);
    root["SensorID"] = Json::Value((int)aSensor->GetPlatform()->GetIndex());
    root["SensorName"] = Json::Value(aSensor->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::SensorTrackInitiated(double aSimTime, WsfSensor *aSensor, const WsfTrack *aTrack)
{
    Json::Value root;
    root["MsgType"] = Json::Value("SensorTrackInitiated");
    root["WallTime"] = Json::Value(aSimTime);
    root["SensorID"] = Json::Value((int)aSensor->GetPlatform()->GetIndex());
    root["SensorName"] = Json::Value(aSensor->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}

// WsfWeaponObserver
void ObserverEventInterface::WeaponFireAborted(double aSimTime, WsfWeapon *aWeapon, const WsfTrack *aTrack, double aTime)
{
    Json::Value root;
    root["MsgType"] = Json::Value("WeaponFireAborted");
    root["WallTime"] = Json::Value(aSimTime);
    root["WeaponName"] = Json::Value(aWeapon->GetName());
    root["TargetIndex"] = Json::Value(aTrack->GetTargetIndex());
    root["FireTime"] = Json::Value(aTime);

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::WeaponFired(double aSimTime, const WsfWeaponEngagement *aEngagement, const WsfTrack *aTrack)
{
}
void ObserverEventInterface::WeaponFireRequested(double aSimTime, WsfWeapon *aWeapon, const WsfTrack *aTrack, double aTime)
{
    Json::Value root;
}
void ObserverEventInterface::WeaponPlatformPendingAdd(double aSimTime, WsfPlatform *aPlatform, const WsfWeaponEngagement *aEngagement, const WsfTrack *aTrack)
{
}
void ObserverEventInterface::WeaponHit(double aSimTime, const WsfWeaponEngagement *aEngagement, WsfPlatform *aTarget)
{
}
void ObserverEventInterface::WeaponKilled(double aSimTime, WsfWeapon *aWeapon)
{
    Json::Value root;
    root["MsgType"] = Json::Value("WeaponKilled");
    root["WallTime"] = Json::Value(aSimTime);
    root["WeaponID"] = Json::Value((int)aWeapon->GetPlatform()->GetIndex());
    root["WeaponName"] = Json::Value(aWeapon->GetName());

    Json::FastWriter fw;
    std::string msg = fw.write(root);
    SendPacket(msg);
}
void ObserverEventInterface::WeaponMissed(double aSimTime, const WsfWeaponEngagement *aEngagement, WsfPlatform *aTarget)
{
}